Run Decorator Code¶
Important for Decorators:
The decorator code itself runs when the decorator is APPLIED to the decorated function,
rather than when the decorated function is called!!!
Example 1¶
registry = []
def register(decorated):
''' Decorator '''
registry.append(decorated)
return decorated
# Any function that receives the @register decorator
# will have itself appended to registry list
@register
def func_01(x=3):
return x
@register
def func_02():
return None
@register
def func_03(x=5):
return x
func_results = []
for func in registry:
func_results.append(func())
print(func_results)
# [3, None, 5]
# call functions
res = func_01(4)
res = func_01(8)
res = func_03(3)
res = func_02()
res = func_03(9)
func_results = []
for func in registry:
func_results.append(func())
print(func_results)
# [3, None, 5] - not changed!
Example 2¶
class Registry(object):
def __init__(self):
self._functions = []
def register(self, decorated):
self._functions.append(decorated)
return decorated
def run_all(self, *args, **kwargs):
return_values = []
for func in self._functions:
return_values.append(func(*args, **kwargs))
return return_values
r1 = Registry()
r2 = Registry()
@r1.register
def func_01(x=3):
return x
@r2.register
def func_02(x=5):
return x
@r1.register
@r2.register
def func_03(x=7):
return x
# Running the code from either registry’s run_all method gives the following results
print(r1.run_all())
# [3, 7]
print(r2.run_all())
# [5, 7]
# Notice that the run_all method is able to take arguments,
# which it then passes to the underlying functions when they are run.
print(r1.run_all(x=4))
# [4, 4]